package com.pay.ioopos;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.text.TextPaint;
import android.util.Log;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class SubScreenFactory {
    private static final String TAG = SubScreenFactory.class.getSimpleName();
    private static final char[] CHARS = "0123456789ABCDEF".toCharArray();
    private static final String PATH = "/dev/sub_lcm";
    private static final int WIDTH = 480;
    private static final int HEIGHT = 320;
    private static final ExecutorService service = Executors.newFixedThreadPool(1);
    private static Future future;
    private static Runnable preRunnable;

    public static Bitmap createBitmap() {
        return Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.RGB_565);
    }

    public static Bitmap scaledBitmap(Bitmap bitmap) {
        return Bitmap.createScaledBitmap(bitmap.copy(Bitmap.Config.RGB_565, true),WIDTH,HEIGHT,true);
    }

    public static void flush(Bitmap bitmap) {

        StringBuffer sBuffer = new StringBuffer();
        int count = bitmap.getByteCount();
        ByteBuffer buf = ByteBuffer.allocate(count);
        bitmap.copyPixelsToBuffer(buf);
        bitmap.recycle();
        byte[] byteArray = buf.array();
        for (int i = 0; i < count/2; i++) {
            sBuffer.append(CHARS[(byteArray[2*i+1] & 0xf0) >> 4]);
            sBuffer.append(CHARS[byteArray[2*i+1] & 0x0f]);
            sBuffer.append(CHARS[(byteArray[2*i] & 0xf0) >> 4]);
            sBuffer.append(CHARS[byteArray[2*i] & 0x0f]);
        }
        flush(sBuffer);
    }

    public static void startSubScreen(Runnable runnable) {
        startFlush(runnable, false);
    }

    public static void startSubScreen(Runnable runnable, boolean merge) {
        startFlush(runnable, merge);
    }

    public static void startSubScreenToWelcome(Context context) {
        startSubScreen(() -> flushSubScreenToWelcome(context));
    }

    public static void flushSubScreenToWelcome(Context context) {
        if (null == context) {
            return;
        }

        Canvas canvas;
        Bitmap bitmap = SubScreenBackgroudLoader.getInstance().getPayInitBitmap();
        if (null == bitmap) {
            bitmap = createBitmap();
            canvas = new Canvas(bitmap);
            canvas.drawColor(Color.WHITE);
        } else {
            bitmap = scaledBitmap(bitmap);
            canvas = new Canvas(bitmap);
        }

        TextPaint paint = new TextPaint();
        paint.setColor(context.getColor(R.color.colorSuccess));
        paint.setTextSize(50f);
        paint.setAntiAlias(true);

        String text = "欢迎光临";
        int fontWidth = (int) paint.measureText(text);
        int startX = (bitmap.getWidth() - fontWidth) / 2;
        canvas.drawText(text, startX, 190, paint);

        canvas.save();
        canvas.restore();

        flush(bitmap);

    }

    private static synchronized void startFlush(Runnable runnable, boolean merge) {
        if (null == future) {
            future = service.submit(runnable);
            return;
        }
        future.cancel(false);
        if (merge) {
            Runnable dstPreRunnable = preRunnable::run;
            Runnable newRunnable = () -> {
                dstPreRunnable.run();
                runnable.run();
            };
            future = service.submit(newRunnable);
        } else {
            future = service.submit(runnable);
        }
        preRunnable = runnable::run;

    }

    private static synchronized void flush(StringBuffer sBuffer) {
        try(FileWriter fw = new FileWriter(PATH); BufferedWriter bw = new BufferedWriter(fw)) {
            for (int m = 0; m < 80; m++) {
                bw.write(sBuffer.toString(), m * 7680, 7680);
                bw.flush();
            }
        } catch (Exception e) {
            Log.e(TAG, "subsreen flush: ", e);
        }
    }

}
